package com.flute.haflute.jobbox.communication;

import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flute.haflute.jobbox.common.CloudConstants;
import com.flute.haflute.jobbox.common.CloudContext;
import com.flute.haflute.tools.ClusterUtils;

/**
 * 子节点通信平台API实现
 * 
 */
public class ChildCommunicationService {
	private static Logger logger = LoggerFactory
			.getLogger(ChildCommunicationService.class);
	private static final long serialVersionUID = 500088768362197972L;

	/** 主节点的通信API */
	private static CommunicationServiceFactory serviceFac = null;

	public ChildCommunicationService() {
		if (serviceFac == null)
			init();
	}

	/** 从主节点获取通信接口并保持连接 */
	private static void init() {
		logger.info("begin to lookup RMI registry on IP: {} ,port: {}",
				CloudContext.getCloudMaster(), CloudContext.getRMIPort());

		String service = "rmi://" + CloudContext.getCloudMaster() + ":"
				+ CloudContext.getRMIPort() + "/"
				+ CloudConstants.COMMUNICATION_SERV_CENTER;

		logger.debug("rmi service: {}", service);

		boolean inited = false;
		for (int i = 0; i < 3; i++) {
			try {
				serviceFac = (CommunicationServiceFactory) Naming
						.lookup(service);
				inited = true;
				break;
			} catch (Exception e) {
				logger.error("init ClientServiceFactoryImpl error", e);
				e.printStackTrace();
				try {
					long waittime = 1000L * (i * 3 + 1);
					System.out.println("will try in " + waittime + " seconds");
					Thread.sleep(waittime);
				} catch (InterruptedException e1) {
				}
			}
		} // end for
		if (!inited) {
			System.out.println("can NOT connect to master, please retry later");
			ClusterUtils.exitGracefully();
		}

		logger.info("lookup RMI registry successful ");
	}

	/** 取得messagerName标识的消息器,在节点之间通信使用 */
	public Remote getMessager(String messagerName) throws RemoteException {
		return serviceFac.getMessager(messagerName);
	}

	/** 取得主节点的消息通知器,所有任务消息从该消息器获得 */
	public ClientService2Server getMasterNotifier() throws RemoteException {
		return serviceFac.getNotifier();
	}

	/** 连接到主节点并获取到唯一的编号 */
	public int connect2Master() throws RemoteException {
		if (serviceFac == null) {
			init();
		}
		return serviceFac.getDaemonNo(CloudContext.getLocalIP());
	}

	public static void initConnection2NewMaster() {
		init();
	}
}
